#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>

#define CAN_INTERFACE "can0"

void setup_can_interface(int s) {
    struct ifreq ifr;
    struct sockaddr_can addr;

    strcpy(ifr.ifr_name, CAN_INTERFACE);
    ioctl(s, SIOCGIFINDEX, &ifr);

    addr.can_family = AF_CAN;
    addr.can_ifindex = ifr.ifr_ifindex;

    bind(s, (struct sockaddr *)&addr, sizeof(addr));
}

void send_can_message(int s) {
    struct can_frame frame;
    frame.can_id = 0x123;
    frame.can_dlc = 8;
    for (int i = 0; i < 8; i++) {
        frame.data[i] = i;
    }
    
    if (write(s, &frame, sizeof(struct can_frame)) != sizeof(struct can_frame)) {
        perror("Write");
        exit(EXIT_FAILURE);
    }

    printf("Sent CAN message\n");
    
}

void receive_can_message(int s) {
    struct can_frame frame;
    int nbytes = 0;
    
    nbytes = read(s, &frame, sizeof(struct can_frame));
    if (nbytes < 0) {
        perror("Read");
        exit(EXIT_FAILURE);
    }

    printf("Received CAN message with ID: 0x%X\n", frame.can_id);
    printf("Data: ");
    for (int i = 0; i < frame.can_dlc; i++) {
        printf("%02X ", frame.data[i]);
    }
    printf("\n");
   
}

int main() {
    int s = socket(PF_CAN, SOCK_RAW, CAN_RAW);
    if (s < 0) {
        perror("Socket");
        return 1;
    }

    setup_can_interface(s);

    send_can_message(s);
    
    receive_can_message(s);

    close(s);
    return 0;
}

